package com.xlong.k329;

import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.smart.command.CpclCommand;
import com.xlong.k329.databinding.ActivityMainBinding;

import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Vector;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration appBarConfiguration;
    private ActivityMainBinding binding;
    private ThreadPool threadPool;
    ArrayList<String> per = new ArrayList<>();
    private static final String driver = "net.sourceforge.jtds.jdbc.Driver";//"com.mysql.jdbc.Driver";
    //这里是SQL的用户名
    private static final String user = "sa";
    //private static final String password = "WWW.prevail.com";
    private static final String password = "WWW.prevail-catv.com";
    public static SharedPreferencesUtils helper;

    private static final int REQUEST_CODE = 0x004;
    /**
     * Connection status disconnected
     */
    private static final int CONN_STATE_DISCONN = 0x007;
    /**
     * Use printer command error
     */
    private static final int PRINTER_COMMAND_ERROR = 0x008;

    private static final int MYSQL_DATA_RETURN = 0x009;
    private static final int MYSQL_DATA_ERR = 0x00A;
    private static final int MYSQL_DATA_DISCONN = 0x00B;

    private static final int CONN_PRINTER = 0x12;

    private String[] permissions = {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.BLUETOOTH
    };

    private void checkPermission() {
        for (String permission : permissions) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, permission)) {
                per.add(permission);
            }
        }
    }

    private void requestPermission() {
        if (per.size() > 0) {
            String[] p = new String[per.size()];
            ActivityCompat.requestPermissions(this, per.toArray(p), REQUEST_CODE);
        }
    }

    public static Activity getActivityFromView(View view) {
        if (null != view) {
            Context context = view.getContext();
            while (context instanceof ContextWrapper) {
                if (context instanceof Activity) {
                    return (Activity) context;
                }
                context = ((ContextWrapper) context).getBaseContext();
            }
        }
        return null;
    }

    /**
     * Bluetooth connectivity
     */
    //蓝牙设备搜索，从该页面跳转到蓝牙设备列表
    public void btnBluetoothConn(View view) {
        startActivityForResult(new Intent(this, BluetoothDeviceList.class), Constant.BLUETOOTH_REQUEST_CODE);
    }

    //蓝牙设备断开连接
    public void btnDisConn(View view) {
        if (DeviceConnFactoryManager.getDeviceConnFactoryManager() == null ||
                !DeviceConnFactoryManager.getDeviceConnFactoryManager().getConnState()) {
            Utils.toast(this, getString(R.string.str_cann_printer));
            return;
        }
        mHandler.obtainMessage(CONN_STATE_DISCONN).sendToTarget();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());//找到根布局

        setSupportActionBar(binding.toolbar);//toolbar取代原来的actionbar

        helper = new SharedPreferencesUtils(this, "setting");

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);

        checkPermission();
        requestPermission();

        //悬浮按钮点击事件——进行扫描二维码
        binding.fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                //        .setAction("Action", null).show();
                //扫描二维码
                new IntentIntegrator(MainActivity.this)
                        .setCaptureActivity(CustomCaptureActivity.class)
                        .setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES)// 扫码的类型,可选：一维码，二维码，一/二维码
                        .setPrompt("请对准二维码")// 设置提示语
                        .setCameraId(0)// 选择摄像头,可使用前置或者后置
                        .setBeepEnabled(true)// 是否开启声音,扫完码之后会"哔"的一声
                        .initiateScan();// 初始化扫码

            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        IntentFilter filter = new IntentFilter();
        filter.addAction(DeviceConnFactoryManager.ACTION_QUERY_PRINTER_STATE);
        filter.addAction(DeviceConnFactoryManager.ACTION_CONN_STATE);
        registerReceiver(receiver, filter);
    }

    /**
     * Disconnect
     */
    private void closePort() {
        if (DeviceConnFactoryManager.getDeviceConnFactoryManager() != null && DeviceConnFactoryManager.getDeviceConnFactoryManager().mPort != null) {
            DeviceConnFactoryManager.getDeviceConnFactoryManager().reader.cancel();
            DeviceConnFactoryManager.getDeviceConnFactoryManager().mPort.closePort();
            DeviceConnFactoryManager.getDeviceConnFactoryManager().mPort = null;
        }
    }

    public void btnCpclPrint(Bundle bundle) {
        if (DeviceConnFactoryManager.getDeviceConnFactoryManager() == null ||
                !DeviceConnFactoryManager.getDeviceConnFactoryManager().getConnState()) {
            Utils.toast(App.getContext(), getString(R.string.str_cann_printer));
            return;
        }
            String str[] = bundle.getString("qrstr").split("&");

        if (str.length < 6) {
            Utils.toast(MainActivity.this, "无效的扫描信息!");
            return;
        } else {
            if (!isNumber(str[str.length - 2])) {
                Utils.toast(MainActivity.this, "扫描二维码有误，Qty非纯数字!");
                return;
            } else {
                if (helper.getString("qty") != null && !helper.getString("qty").equals("") && !helper.getString("qty").equals("0")) {
                    threadPool = ThreadPool.getInstantiation();
                    threadPool.addTask(() -> sendCpcl(bundle));
                } else {
                    Utils.toast(MainActivity.this, "数量(Qty)中内容为空或者为0，请重新输入数量！");
                    return;
                }

            }
        }
    }

    /**
     * Print face sheet
     */

    //判断字符串数组中是否全为数字
    public static boolean isNumber(String str) {
        if (str == null || str.equals("")) return false;
        for (char c : str.toCharArray()) {
            if (!Character.isDigit(c)) return false;
        }
        return true;

    }


    public static void sendCpcl(Bundle bundle) {
        String qrstr[] = bundle.getString("qrstr").split("&");
        String barcode_qrstr = bundle.getString("qrstr").replace("\r\n", "");

        barcode_qrstr = qrstr[0] + "&" + qrstr[1] + "&" + qrstr[2] + "&" + qrstr[3] + "&" + helper.getString("qty") + "&" + qrstr[qrstr.length - 1];

        //Initialize the cpcl instruction
        CpclCommand cpcl = new CpclCommand();
        //Set sheet height and print copies
        cpcl.addInitializePrinter(340, 1);
        //Print barcode
        cpcl.addBarcodeText(0, 2);
        if (qrstr[0].length() < 7) {
            cpcl.addBarcode(
                    CpclCommand.COMMAND.BARCODE,
                    CpclCommand.BARCODETYPE.CODE128,
                    2,
                    CpclCommand.BARCODERATIO.ThpointZ2,
                    30,
                    30,
                    15,
                    qrstr[0]
            );
            cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 50, "P/N:");
        } else if (qrstr[0].length() < 11) {
            cpcl.addBarcode(
                    CpclCommand.COMMAND.BARCODE,
                    CpclCommand.BARCODETYPE.CODE128,
                    1,
                    CpclCommand.BARCODERATIO.ThpointZ2,
                    30,
                    30,
                    15,
                    qrstr[0]
            );
            cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 50, "P/N:");
        } else {
            /*cpcl.addBarcode(
                CpclCommand.COMMAND.BARCODE,
                CpclCommand.BARCODETYPE.CODE128,
                1,
                CpclCommand.BARCODERATIO.OpointF,
                30,
                30,
                15,
                qrstr[0]
            )*/
            cpcl.addText(CpclCommand.TEXT_FONT.FONT_91, 0, 30, 40, "P/N:" + qrstr[0]);
        }
        //Print qrcode
        //String qr = bundle.getString("qrstr");
        //qr = qr.replace("\r\n","");
        cpcl.addBQrcode(CpclCommand.QRCODE_LEVEL.H, CpclCommand.MODE.A, 350, 15, 2, 3, barcode_qrstr);

        //cpcl.addBarcodeText(1, 2);
        cpcl.addBarcode(CpclCommand.COMMAND.BARCODE, CpclCommand.BARCODETYPE.CODE128, 1, CpclCommand.BARCODERATIO.ThpointF, 30, 30, 75, qrstr[1]);
        cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 110, "Co:");

        //cpcl.addBarcodeText(1, 2);
        cpcl.addBarcode(CpclCommand.COMMAND.BARCODE, CpclCommand.BARCODETYPE.CODE128, 1, CpclCommand.BARCODERATIO.TpointN, 30, 30, 135, qrstr[2]);
        cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 170, "D/T:");

        //cpcl.addBarcodeText(1, 2);

        if (helper.getString("qty") != null) {
            cpcl.addBarcode(CpclCommand.COMMAND.BARCODE, CpclCommand.BARCODETYPE.CODE128, 2, CpclCommand.BARCODERATIO.ThpointZ2, 30, 30, 195, helper.getString("qty"));
        } else {
            cpcl.addBarcode(CpclCommand.COMMAND.BARCODE, CpclCommand.BARCODETYPE.CODE128, 2, CpclCommand.BARCODERATIO.TpointFo, 30, 30, 195, "1000");
        }

        cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 230, "Qty:");

        //品名
        cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 275, "品名：" + bundle.getString("pname"));

        //规格
        String modelstr = bundle.getString("mname");
        if (modelstr == null) {
            cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 315, "规格：");
            //return;
        } else {
            if (modelstr.length() < 44) {
                cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 315, "规格：" + modelstr);
            } else {
                cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 30, 305, "规格：" + modelstr.substring(0, 40));
                cpcl.addText(CpclCommand.TEXT_FONT.FONT_20, 0, 70, 325, modelstr.substring(40));
            }
        }


        //Set alignment to left
        cpcl.addJustification(CpclCommand.ALIGNMENT.LEFT);
        //Print
        cpcl.addPrint();
        Vector<Byte> datas = cpcl.getCommand();

        // Send cpcl data
        DeviceConnFactoryManager.getDeviceConnFactoryManager().sendDataImmediately(datas);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        View firstFragmentView = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_content_main).getView();//获取FirstFragment视图
        EditText editText = firstFragmentView.findViewById(R.id.txt_printCount);//获取FirstFragment中的控件
        String firstFraEditcontent = editText.getText().toString();//获取editText中的内容
        int printCount = Integer.parseInt(firstFraEditcontent);//转换数据类型

        if (resultCode == RESULT_OK) {
            switch (requestCode) {

                //Bluetooth connect
                case Constant.BLUETOOTH_REQUEST_CODE: {
                    closePort();
                    //Get bluetooth mac address
                    String macAddress = data.getStringExtra(BluetoothDeviceList.EXTRA_DEVICE_ADDRESS);
                    //Init DeviceConnFactoryManager
                    new DeviceConnFactoryManager.Build()
                            .setConnectMethod(DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH)
                            //Set bluetooth mac address
                            .setMacAddress(macAddress)
                            .build();
                    //Open port
                    threadPool = ThreadPool.getInstantiation();
                    threadPool.addTask(() -> DeviceConnFactoryManager.getDeviceConnFactoryManager().openPort());

                    break;
                }
                default:
                    //扫码结果
                    IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
                    if (intentResult != null) {
                        if (intentResult.getContents() == null) {
                            //扫码失败
                        } else {

                            String result = intentResult.getContents().substring(0, intentResult.getContents().lastIndexOf("&"));//返回值

                            //qrcode.setText("扫码结果：" + result);
                            Toast.makeText(this, "Scanned: " + result, Toast.LENGTH_SHORT).show();

//                            threadPool = ThreadPool.getInstantiation();
//                            threadPool.addTask(() -> getNewSn(result));

                            if (printCount >= 1 && printCount <= 10) {
                                for (int i = 1; i <= printCount; i++) {
                                    ThreadPool.getInstantiation().addTask(() -> getNewSn(result));
                                }
                            } else {
                                Toast.makeText(this, "输入超出正常范围", Toast.LENGTH_SHORT).show();
                            }

                            //threadPool.addTask(() -> getEthData(result));
                        }
                    }
                    break;
            }
        }

    }

    //广播接收蓝牙信息，重写onReceive方法
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case DeviceConnFactoryManager.ACTION_CONN_STATE:
                    int state = intent.getIntExtra(DeviceConnFactoryManager.STATE, -1);
                    switch (state) {
                        case DeviceConnFactoryManager.CONN_STATE_DISCONNECT:
                            Toast.makeText(MainActivity.this, "未连接", Toast.LENGTH_SHORT).show();
                            break;
                        case DeviceConnFactoryManager.CONN_STATE_CONNECTING:
                            Toast.makeText(MainActivity.this, getString(R.string.str_conn_state_connecting), Toast.LENGTH_SHORT).show();
                            break;
                        case DeviceConnFactoryManager.CONN_STATE_CONNECTED:
                            Toast.makeText(MainActivity.this, getString(R.string.str_conn_state_connected) + "\n" + getConnDeviceInfo(), Toast.LENGTH_SHORT).show();

                            break;
                        case DeviceConnFactoryManager.CONN_STATE_FAILED:
                            Utils.toast(MainActivity.this, getString(R.string.str_conn_fail));

                            break;
                        default:
                            break;
                    }
                    break;
                case DeviceConnFactoryManager.ACTION_QUERY_PRINTER_STATE:

                    break;
                default:
                    break;
            }
        }
    };

    private String getConnDeviceInfo() {
        String str = "";
        DeviceConnFactoryManager deviceConnFactoryManager = DeviceConnFactoryManager.getDeviceConnFactoryManager();
        if (deviceConnFactoryManager != null
                && deviceConnFactoryManager.getConnState()) {
            if (deviceConnFactoryManager.getConnMethod() == DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH) {
                str += "BLUETOOTH\n";
                str += "MacAddress: " + deviceConnFactoryManager.getMacAddress();
            } else if (deviceConnFactoryManager.getConnMethod() == DeviceConnFactoryManager.CONN_METHOD.WIFI) {
                str += "WIFI\n";
                str += "ip: " + deviceConnFactoryManager.getIp() + "\n";
                str += "port: " + deviceConnFactoryManager.getPort();
            }
        }
        return str;
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case CONN_STATE_DISCONN:
                    if (DeviceConnFactoryManager.getDeviceConnFactoryManager() != null ||
                            !DeviceConnFactoryManager.getDeviceConnFactoryManager().getConnState()) {
                        DeviceConnFactoryManager.getDeviceConnFactoryManager().closePort();
                        Utils.toast(MainActivity.this, getString(R.string.str_disconnect_success));
                    }
                    break;
                case PRINTER_COMMAND_ERROR:
                    Utils.toast(MainActivity.this, getString(R.string.str_choice_printer_command));
                    break;
                case CONN_PRINTER:
                    Utils.toast(MainActivity.this, getString(R.string.str_cann_printer));
                    break;
                case MYSQL_DATA_RETURN:
                    Bundle bundle = msg.getData();
                    btnCpclPrint(bundle);
                    break;
                case MYSQL_DATA_ERR:
                    Utils.toast(MainActivity.this, "数据库操作失败!");
                    break;
                case MYSQL_DATA_DISCONN:
                    Utils.toast(MainActivity.this, "数据库连接失败!");
                    break;
            }
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(receiver);
        if (DeviceConnFactoryManager.getDeviceConnFactoryManager() != null) {
            DeviceConnFactoryManager.getDeviceConnFactoryManager().closePort();
        }
        if (threadPool != null) {
            threadPool.stopThreadPool();
            threadPool = null;
        }
        super.onDestroy();
    }

    public static Connection getConn(String dbip, String port, String dbName) {
        Connection connection = null;
        try {
            Class.forName(driver);
            //数据的IP地址，本文中的地址不是我的真实地址，请换为你的真实IP地址。
            //String url = "jdbc:mysql://" + dbip + ":" + port +"/" + dbName;
            //connection= DriverManager.getConnection(url, user, password);

            connection = DriverManager.getConnection("jdbc:jtds:sqlserver://" + dbip + ":" + port + "/" + dbName + ";charset=utf8", user, password);
            Log.e("数据库连接", "成功!");
        } catch (Exception e) {
            Log.e("数据库连接", "失败!");
            e.printStackTrace();
        }
        return connection;
    }

    public void getEthData(String qrstr) {
        if (qrstr == "") {
            Utils.toastLong(MainActivity.this, "获取流水码失败!");
            return;
        }
        String rsdata[] = new String[2];
        Connection connection = getConn(helper.getString("dbip"), helper.getString("dbport"), helper.getString("dbname"));
        Message msg = Message.obtain();
        Bundle bundle = new Bundle();
        if (connection != null) {
            String sql = "select cInvName,cInvStd from " + helper.getString("dbname") + ".dbo.Inventory where cInvCode='" + qrstr.split("&")[0] + "'";
            //String sql="select pname,mname from tbl_products where sn = " + qrstr.split("&")[0];
            try {
                java.sql.Statement statement = connection.createStatement();
                ResultSet rSet = statement.executeQuery(sql);
                while (rSet.next()) {
                    rsdata[0] = rSet.getString("cInvName");
                    rsdata[1] = rSet.getString("cInvStd");
                }
                connection.close();
                msg.what = MYSQL_DATA_RETURN;
                bundle.putString("pname", rsdata[0]);
                bundle.putString("mname", rsdata[1]);
                bundle.putString("qrstr", qrstr);
                msg.setData(bundle);
            } catch (SQLException e) {
                e.printStackTrace();
                msg.what = MYSQL_DATA_ERR;
            }
        } else {
            msg.what = MYSQL_DATA_DISCONN;
        }

        mHandler.sendMessage(msg);
        return;
    }

    public void getNewSn(String qrstr) {
        new HttpAsyncTask().execute(qrstr);

    }

    private class HttpAsyncTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            // 在这里执行网络请求
            OkHttpClient client = new OkHttpClient();

            MediaType JSON = MediaType.parse("application/json; charset=utf-8");
            RequestBody body = RequestBody.create("{}", JSON);
            Request request = new Request.Builder()
                    .url("http://192.168.18.253:5003/MesItem/ItemSerinal") // 替换为你的API地址
                    .post(body)
                    .build();

            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                // 打印和返回响应体
                //System.out.println(response.body().string());
                String rsp = response.body().string();
                JSONObject respjson = new JSONObject(rsp);
                if (respjson.getString("code").equals("0")) {
                    return "";
                }
                //return params[0] + "&" + respjson.getJSONArray("data").getString(0);
                getEthData(params[0] + "&" + respjson.getJSONArray("data").getString(0));
                return "";
            } catch (IOException | JSONException e) {
                e.printStackTrace();
                return "";
            }
        }

        @Override
        protected void onPostExecute(String result) {
            // 这个方法会在主线程中运行，用于更新 UI
            // result 参数是 doInBackground 方法返回的结果
            //Log.i("xxxxxxxxx" , result);
            //getEthData(result);
        }
    }
}